package com.dony.shop.service.impl;

import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dony.common.utils.SecurityUtils;
import com.dony.common.utils.StringUtils;
import com.dony.shop.domain.*;
import com.dony.shop.domain.vo.GlobalProductVo;
import com.dony.shop.mapper.PublishTaskMapper;
import com.dony.shop.service.*;
import com.dony.shop.util.ShopeeUtil;
import com.dony.shop.util.TransUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Collectors;

/**
 * @author sundw
 * @date 2022-08-30
 */
@Slf4j
@Service
public class PublishTaskServiceImpl extends ServiceImpl<PublishTaskMapper, PublishTask> implements IPublishTaskService {

    @Autowired
    ShopeeUtil shopeeUtil;
    @Resource
    IGlobalModelService globalModelService;
    @Resource
    IShopeeShopService shopService;
    @Resource
    IShopeeMerchantService merchantService;
    @Resource
    IGlobalProductService globalProductService;
    @Resource
    IPriceConfigService priceConfigService;
    @Resource
    IItemService shopItemService;
    @Resource
    ThreadPoolTaskExecutor executor;
    @Resource
    TransUtil transUtil;

    @Override
    public Boolean publishBatch(List<GlobalProductVo> products) {
        //封装数据
        products.stream().filter(pr -> pr.getGlobalItemId() != null)
                .forEach(pro -> {
                    Map<Float, JSONObject> priceMap = new HashMap<>();
                    //把价格表放入map中
                    priceMap.put(pro.getPrice().getGlobalPrice(), globalProductService.getPriceJo(pro.getPrice()));
                    if (pro.getHasChildren()) {
                        //获取子类
                        products.stream()
                                //找到同源价格
                                .filter(pr -> pro.getGlobalItemId().equals(pr.getParentId()))
                                .forEach(pr -> {
                                    //这里应该放全球价格，因为这个价格不会变化
                                    //把价格表放入map中
                                    priceMap.put(pr.getPrice().getGlobalPrice(), globalProductService.getPriceJo(pr.getPrice()));
                                });
                    }
                    //使用线程池调用发布
                    executor.execute(() -> {
                        //调用发布接口
                        List<PublishTask> publishList = publish(pro, priceMap);
                        //添加到发布表
                        this.saveBatch(publishList);
                    });
                });
        //添加商品的活动数据
        return true;
    }

    @Override
    public List<PublishTask> listByParam(PublishTask publishTask) {
        QueryWrapper<PublishTask> wrapper = new QueryWrapper<>();
        wrapper.between("status", -1, 1);
        //if (publishTask.getMerchantId() != null) {
        wrapper.eq("merchant_id", publishTask.getMerchantId());
        //}
        if (publishTask.getProName() != null) {
            wrapper.like("pro_name", publishTask.getProName());
        }
        wrapper.eq("tenant_id", SecurityUtils.getDeptId());
        wrapper.orderByDesc("create_time");
        return list(wrapper);
    }

    @Override
    public List<PublishTask> sycnStatus(Long[] publishTask) {
        List<PublishTask> publishTasks = this.listByIds(Arrays.asList(publishTask));
        List<CompletableFuture<PublishTask>> futures = publishTasks.stream().map(task -> {
            CompletableFuture<PublishTask> future = CompletableFuture.supplyAsync(() -> getPublishTaskFromShopee(task), executor);
            return future;
        }).collect(Collectors.toList());

        //编排异步线程
        CompletableFuture<Void> allFuture = CompletableFuture.allOf(futures.toArray(new CompletableFuture[futures.size()]));
        //获取处理的结果
        CompletableFuture<List<PublishTask>> futureResults = allFuture.thenApply(v ->
                futures.stream()
                        .map(CompletableFuture::join)
                        .collect(Collectors.toList())
        );
        List<PublishTask> tasks = futureResults.join().stream().filter(task -> task!=null).collect(Collectors.toList());
        this.updateBatchById(tasks);
        return tasks;

    }

    private PublishTask getPublishTaskFromShopee(PublishTask task) {
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("publish_task_id", task.getPublishTaskId());
        JSONObject response = shopeeUtil.merchantGetHandler("/api/v2/global_product/get_publish_task_result", task.getMerchantId(), paramMap);
        if (response == null) {
            log.error("发布任务ID：{}", task.getPublishTaskId());
            return null;
        }
        String publishStatus = response.getString("publish_status");
        //如果发布成功
        if (StringUtils.equals(publishStatus, "success")) {
            JSONObject success = response.getJSONObject("success");
            task.setRegion(success.getString("region"));
            task.setShopId(success.getLong("shop_id"));
            task.setItemId(success.getLong("item_id"));
            task.setStatus(1);
            //更新店铺商品信息
            Item shopItem = shopItemService.syncShopItemByItemId(task.getShopId(), task.getItemId());
            if (shopItem != null) {
                task.setItemStatus(shopItem.getItemStatus());
            }
        } else {
            task.setStatus(-1);
            JSONObject failed = response.getJSONObject("failed");
            task.setFailedReason(failed.getString("failed_reason"));
            log.error("查询到发布失败的任务：publish_task_id：{}---》详情：{}", task.getPublishTaskId(), task.toString());
        }
        return task;
    }

    @Override
    public Boolean checkAndRemoveByIds(List<Long> publishTaskIds) {
        if (CollectionUtils.isEmpty(publishTaskIds)) {
            return false;
        }
        List<PublishTask> publishTasks = this.listByIds(publishTaskIds);
        List<PublishTask> deleteList = publishTasks.stream().filter(publishTask ->
                publishTask.getStatus() == -1 || StringUtils.equals("DELETED", publishTask.getItemStatus())
        ).map(task -> {
            task.setStatus(-2);
            return task;
        }).collect(Collectors.toList());
        this.updateBatchById(deleteList);
        return true;
    }



    /**
     * 发布单个全球商品
     *
     * @param gProduct
     * @return
     */
    public List<PublishTask> publish(GlobalProductVo gProduct, Map<Float, JSONObject> priceMap) {
        //获取可以发布的店铺
        //查询当前商户可以发布的店铺
        List<ShopeeShop> publishShops = shopService.getPublishShopListByMerchant(gProduct.getMerchantId());
        //查询商户的租户Id
        Long tenantId = merchantService.getTenantByMerchant(gProduct.getMerchantId());
        List<PublishTask> publishIds = publishShops.stream().map(shop -> {
            //封装数据
            Map<String, Object> paramMap = new HashMap<>();
            paramMap.put("global_item_id", gProduct.getGlobalItemId());
            paramMap.put("shop_id", shop.getShopId());
            paramMap.put("shop_region", shop.getRegion());
            List<GlobalModel> globalModels = globalModelService.list(new QueryWrapper<GlobalModel>().eq("global_item_id", gProduct.getGlobalItemId()));
            //封装价格
            Map<String, Object> itemMap = new HashMap<>();
            AtomicBoolean checkPrice = new AtomicBoolean(true);
            List<Map<String, Object>> mapList = globalModels.stream().map(gm -> {
                Map<String, Object> model = new HashMap<>();
                if (gm.getSecondIndex() == null) {
                    model.put("tier_index", new int[]{gm.getFirstIndex()});
                } else {
                    model.put("tier_index", new int[]{gm.getFirstIndex(), gm.getSecondIndex()});
                }
                String country = shop.getRegion().toLowerCase();
                //封装价格
                PriceConfig priceConfig = priceConfigService.selectPriceConfigByMerchantId(gProduct.getMerchantId());
                //如果只有一个价格
                int nowPirce = priceMap.get(gm.getOriginalPrice()).getInteger(country);
                if (nowPirce == 0) {
                    checkPrice.set(false);
                    log.error("商品Id：{} 的价格计算错误！出现了0", gProduct.getGlobalItemId());
                }
                float rate;
                if (StringUtils.equals("vn", country)) {
                    //越南默认设置折扣为80%，如果超过80000则原价上
                    if (nowPirce <= 800000) {
                        rate = 100f / 80;
                        //log.info("越南8折,价格：原价：{}，比例：{},折扣价：{}",nowPirce,rate,nowPirce * rate);
                    } else {
                        //log.info("越南原价");
                        rate = 1f;
                    }
                } else {
                    rate = 100f / priceConfig.getDiscount();
                }
                model.put("original_price", nowPirce * rate);
                //log.info("商品Id：{} 的发布价格：原价：{}--> 折扣后价：{}", gProduct.getGlobalItemId(), nowPirce * rate, nowPirce);
                return model;
            }).collect(Collectors.toList());
            itemMap.put("model", mapList);
            //如果是越南，处理翻译问题
            if (StringUtils.equals("VN", shop.getRegion()) && StringUtils.isNotEmpty(gProduct.getDescription())) {
                //每行前面添加 -
                //String description = gProduct.getDescription();
                //String desc = transUtil.VNTransProcess(description);
                //调用翻译接口
                String handledDesc = transUtil.TransPostHandler(gProduct.getDescription(), "auto", "vie");
                if (StringUtils.isNotEmpty(handledDesc)) {
                    itemMap.put("description", handledDesc);
                }
                //如果翻译失败，应该处理一下
            }
            paramMap.put("item", itemMap);
            //发布前价格检查
            if (mapList == null || mapList.size() == 0 || !checkPrice.get()) {
                log.error("商品Id：{} 的价格出错！请仔细检查价格！", gProduct.getGlobalItemId());
                return null;
            }
            JSONObject response = shopeeUtil.merchantPostHandler("/api/v2/global_product/create_publish_task", gProduct.getMerchantId(), paramMap);
            if (response == null) {
                log.error("商品发布失败！商家：{}，商品名称：{}", gProduct.getMerchantId(), gProduct.getGlobalItemName());
                return null;
            }
            //封装发布对象
            PublishTask publishTask = new PublishTask();
            publishTask.setRegion(shop.getRegion());
            publishTask.setPublishTaskId(response.getLong("publish_task_id"));
            publishTask.setStatus(0);
            publishTask.setImage(gProduct.getImageMini());
            publishTask.setMerchantId(gProduct.getMerchantId());
            //租户Id
            publishTask.setTenantId(tenantId);
            publishTask.setProName(gProduct.getGlobalItemName());
            publishTask.setCreateTime(new Date());
            return publishTask;
        }).filter(pt -> pt != null && pt.getPublishTaskId() != null).collect(Collectors.toList());
        return publishIds;
    }

}
